#include "driver.h"

#define SCL LATA0
#define SDA LATA1
#define SDA_IN() (TRISA |= 0x02)
#define SDA_OUT() (TRISA &= 0xFD)
#define SDA_GET() (PORTA&0x02)

#define SCL1 LATA2
#define SDA1 LATA3
#define SDA1_IN() (TRISA |= 0x08)
#define SDA1_OUT() (TRISA &= 0xF7)

#define SCL2 LATA4
#define SDA2 LATA5
#define SDA2_IN() (TRISA |= 0x20)
#define SDA2_OUT() (TRISA &= 0xDF)

#define SCL3 LATB3
#define SDA3 LATB4
#define SDA3_IN() (TRISB |= 0x10)
#define SDA3_OUT() (TRISB &= 0xEF)

void start(void)
{	//H
	SCL = 1;
	SDA = 1;
	NOP();
	NOP();
	SDA = 0;
	NOP();
}
void start1(void)
{	//H
	SCL1 = 1;
	SDA1 = 1;
	NOP();
	NOP();
	SDA1 = 0;
	NOP();
}
void start2(void)
{	//H
	SCL2 = 1;
	SDA2 = 1;
	NOP();
	NOP();
	SDA2 = 0;
	NOP();
}
void start3(void)
{	//H
	SCL3 = 1;
	SDA3 = 1;
	NOP();
	NOP();
	SDA3 = 0;
	NOP();
}

void stop(void)
{	//L
	SDA = 0;
	SCL = 1;
	NOP();
	NOP();
	SDA = 1;
	NOP();
}
void stop1(void)
{	//L
	SDA1 = 0;
	SCL1 = 1;
	NOP();
	NOP();
	SDA1 = 1;
	NOP();
}
void stop2(void)
{	//L
	SDA2 = 0;
	SCL2 = 1;
	NOP();
	NOP();
	SDA2 = 1;
	NOP();
}
void stop3(void)
{	//L
	SDA3 = 0;
	SCL3 = 1;
	NOP();
	NOP();
	SDA3 = 1;
	NOP();
}

void wack(void)
{
	SCL = 0;
	SDA_IN();
	NOP();
	NOP();
	NOP();
	while(SDA_GET());
	SCL = 1;
	NOP();
	NOP();
	SCL = 0;
}

void sendbyte(uint8_t dat)
{
	uint8_t i;
	for(i=0; i<8; i++)
	{
		SCL = 0;
		if(0x80&dat){
			SDA = 1;
		}else{
			SDA = 0;
		}
		NOP();
		NOP();
		dat = dat << 1;
		SCL = 1;
		NOP();
		NOP();
		NOP();
	}
}

void showall(void)
{
	uint8_t i;
	start();
	sendbyte(0x48);
	wack();
	stop();

	start();
	sendbyte(0x79);
	wack();
	for(i=0; i<3; i++)
	{
		sendbyte(0xff);
		wack();
	}
	stop();

	start();
	sendbyte(0x8f);
	wack();
	stop();
}

void sendcmd(uint8_t ca, uint8_t dt)
{
	uint8_t i;

	start();
	for(i=0;i<8;i++)
	{
		SCL = 0;
		if(ca & 0x80){
			SDA = 1;
		}else{
			SDA = 0;
		}
		ca <<= 1;
		SCL = 1;
		NOP();
		NOP();
	}
	SCL = 0;
	SDA_IN();
	NOP();
	NOP();
	SCL = 1;
	NOP();
	SCL = 0;
	SDA_OUT();

	for(i=0;i<8;i++)
	{
		SCL = 0;
		if(dt & 0x80){
			SDA = 1;
		}else{
			SDA = 0;
		}
		dt <<= 1;
		SCL = 1;
		NOP();
		NOP();
	}
	SCL = 0;
	SDA_IN();
	NOP();
	NOP();
	SCL = 1;
	NOP();
	SCL = 0;
	SDA_OUT();

	NOP();
	stop();
}

void sendcmd1(uint8_t ca, uint8_t dt)
{
	uint8_t i;

	start1();
	for(i=0;i<8;i++)
	{
		SCL1 = 0;
		if(ca & 0x80){
			SDA1 = 1;
		}else{
			SDA1 = 0;
		}
		ca <<= 1;
		SCL1 = 1;
		NOP();
		NOP();
	}
	SCL1 = 0;
	SDA1_IN();
	NOP();
	NOP();
	SCL1 = 1;
	NOP();
	SCL1 = 0;
	SDA1_OUT();

	for(i=0;i<8;i++)
	{
		SCL1 = 0;
		if(dt & 0x80){
			SDA1 = 1;
		}else{
			SDA1 = 0;
		}
		dt <<= 1;
		SCL1 = 1;
		NOP();
		NOP();
	}
	SCL1 = 0;
	SDA1_IN();
	NOP();
	NOP();
	SCL1 = 1;
	NOP();
	SCL1 = 0;
	SDA1_OUT();

	NOP();
	stop1();
}

void sendcmd2(uint8_t ca, uint8_t dt)
{
	uint8_t i;

	start2();
	for(i=0;i<8;i++)
	{
		SCL2 = 0;
		if(ca & 0x80){
			SDA2 = 1;
		}else{
			SDA2 = 0;
		}
		ca <<= 1;
		SCL2 = 1;
		NOP();
		NOP();
	}
	SCL2 = 0;
	SDA2_IN();
	NOP();
	NOP();
	SCL2 = 1;
	NOP();
	SCL2 = 0;
	SDA2_OUT();

	for(i=0;i<8;i++)
	{
		SCL2 = 0;
		if(dt & 0x80){
			SDA2 = 1;
		}else{
			SDA2 = 0;
		}
		dt <<= 1;
		SCL2 = 1;
		NOP();
		NOP();
	}
	SCL2 = 0;
	SDA2_IN();
	NOP();
	NOP();
	SCL2 = 1;
	NOP();
	SCL2 = 0;
	SDA2_OUT();

	NOP();
	stop2();
}

void sendcmd3(uint8_t ca, uint8_t dt)
{
	uint8_t i;

	start3();
	for(i=0;i<8;i++)
	{
		SCL3 = 0;
		if(ca & 0x80){
			SDA3 = 1;
		}else{
			SDA3 = 0;
		}
		ca <<= 1;
		SCL3 = 1;
		NOP();
		NOP();
	}
	SCL3 = 0;
	SDA3_IN();
	NOP();
	NOP();
	SCL3 = 1;
	NOP();
	SCL3 = 0;
	SDA3_OUT();

	for(i=0;i<8;i++)
	{
		SCL3 = 0;
		if(dt & 0x80){
			SDA3 = 1;
		}else{
			SDA3 = 0;
		}
		dt <<= 1;
		SCL3 = 1;
		NOP();
		NOP();
	}
	SCL3 = 0;
	SDA3_IN();
	NOP();
	NOP();
	SCL3 = 1;
	NOP();
	SCL3 = 0;
	SDA3_OUT();

	NOP();
	stop3();
}
//---------------------------
#if 0
void sendcdd(uint8_t cmd, uint8_t dat1, uint8_t dat2)
{
	uint8_t i;

	LATA2 = 0;	//CS low

/*send cmd*/
	for(i=0; i<8; i++)
	{	/*150 us clock cycle*/
		__delay_us(30);
		if(cmd & 0x80){
			LATA6 = 1;	//SDO prepare
		}
		else{
			LATA6 = 0;
		}
		__delay_us(70);
		LATA0 = 0;	//CLK low
		__delay_us(50);
		LATA0 = 1;	//CLK high
		cmd <<= 1;
	}

/*send data1*/
	for(i=0; i<8; i++)
	{	/*150 us clock cycle*/
		__delay_us(30);
		if(dat1 & 0x80){
			LATA6 = 1;	//SDO prepare
		}
		else{
			LATA6 = 0;
		}
		__delay_us(70);
		LATA0 = 0;	//CLK low
		__delay_us(50);
		LATA0 = 1;	//CLK high
		dat1 <<= 1;
	}

/*send data2*/
	for(i=0; i<8; i++)
	{	/*150 us clock cycle*/
		__delay_us(30);
		if(dat2 & 0x80){
			LATA6 = 1;	//SDO prepare
		}
		else{
			LATA6 = 0;
		}
		__delay_us(70);
		LATA0 = 0;	//CLK low
		__delay_us(50);
		LATA0 = 1;	//CLK high
		dat2 <<= 1;
	}

/*tail*/
	__delay_us(20);
	LATA2 = 1;	//CS high, keep 50us
	__delay_us(10);
	LATA6 = 1;	//SDO back
	__delay_us(40);
}
#endif